#include "print.h"
#include "mm.h"
#include "package.h"
#include <stdio.h>
#include <stdlib.h>

void printCons (CFCons * object);
void printVector (int size, void ** vector);
void printString(char * word);

void printObject (void * object)
{
  int location = MMGetType(object);

  switch(location)
    {
    case CFINTEGER_TYPE:
      printf("%d", MMIntegerValue(object));
      break;
			
    case CFFLOAT_TYPE:
      printf("%e", MMDoubleValue(object));
      break;
			
    case CFSYMBOL_TYPE:
      if(MMSymbolPackage(object) == PKGSystemPackage)
	printf("%s", MMSymbolName(object));
      else
	if(MMSymbolPackage(object) == PKGKeywordPackage)
	  printf(":%s", MMSymbolName(object));
	else
	  printf("%s:%s", MMPackageName(MMSymbolPackage(object)),
		 MMSymbolName(object));
						
      break;
			
    case CFCONS_TYPE:
      printf("(");
      printCons ((CFCons *) object);
      printf(")");
      break;
    case CFVECTOR_TYPE:
      printf ("#<Vector:%d:", MMVectorSize(object));
      printf (":");
      printVector (MMVectorSize(object), 
		   MMVectorCell(object));
      printf (")");
      break;
    case CFCHARACTER_TYPE:
      printf("$%c", MMCharValue (object));
      break;
    case CFSTRING_TYPE:
#ifdef DEBUG3
      printf("#<String:%d:", MMStringLength(object));
#endif
      printf("\"");
      printString (MMStringString (object));
      printf("\"");

#ifdef DEBUG3
      printf(">");
#endif
      break;
    default: 
      printf("#<ObjectUnknow:%d:0x%x>", location,(unsigned int) object);
    }
}

void printCons (CFCons * object)
{
  int locationCons = MMGetType(MMCdr(object));
  printObject (MMCar(object));
  if (locationCons == CFCONS_TYPE)
    {
      printf(" ");
      printCons(MMCdr(object));
    }else
    if (MMCdr(object) == MMNil())
      {
	return;
      }else
      {
	printf(" . ");
	printObject(MMCdr(object));
      }
		
}

void printVector (int size, void ** vector)
{
  int i=0;
  printf("(");
  for (i=0; i<size; i++)
    {
      printObject (vector[i]);
      if (!(i = size - 1))
	{
	  printf(" ");
	}
    }
  printf(")");
}

void printString(char * word)
{
  int i=0;
  
  while(word[i] != '\0')
    {
      putchar(word[i]);
      i++;
    }
}

void print (void * object)
{
  printObject (object);
  printf ("\n");
}
